<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>切换主题 dark、light、system</title>


    <style>
        /* dark 主题  */
        [data-theme="dark"] {
            --text-color: white;
            --background-color: black;
        }

        /* light 主题  */
        [data-theme="light"] {
            --text-color: black;
            --background-color: white;
        }

        body {
            color: var(--text-color);
            background-color: var(--background-color);
        }
    </style>
</head>

<body>
    <h1>跟随设备切换主题</h1>
    <p>这是一段测试文本。</p>
    <img src="https://www4.bing.com//th?id=OHR.GoliathHeron_ZH-CN2413747227_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp&w=360&h=202"
        alt="">
    <!-- 下拉框 -->
    <select id="select-wrap" title="切换主题">
        <option value="light">light</option>
        <option value="dark">dark</option>
        <option value="system">system</option>
    </select>

    <script>
        const selectWrap = document.querySelector('#select-wrap');
        const bodyTheme = document.querySelector('body');

        window.onload = () => {
            // 获取用户的选择
            const theme = localStorage.getItem('theme');
            // 如果用户选择了主题，就设置主题同时改变下拉框的选中项
            if (theme) {
                // 设置下拉框的选中项
                selectWrap.value = theme;
                // 动态设置 system 主题
                setTheme()
            }
        }

        // 监听下拉框的变化
        selectWrap.onchange = () => {
            setTheme()
            localStorage.setItem('theme', selectWrap.value);
        }

        // 动态设置 system 主题 函数
        function setTheme() {
            /* 
            下拉框改变时，先移除 system 主题，因为dark、light主题不需要使用系统主题，
            系统主题只需要在下拉框选择 system 时才需要使用，动态添加，解决系统切换主题时，项目不需要刷新
            */
            removeSystemLink()
            if (selectWrap.value === 'system') {
                setTimeout(() => {
                    const link = document.createElement('link');
                    link.rel = 'stylesheet';
                    link.href = './system.css';
                    // 加上名称方便找到移除
                    link.id = 'system';
                    // 在head中插入link 添加到最后
                    document.head.appendChild(link);
                }, 0);
                // 在某个元素前面插入一个元素 语法：parentElement.insertBefore(newElement, targetElement)
                // parentElement是要插入新元素的父元素，newElement是要插入的新元素对象，targetElement是当前元素的前一个兄弟元素，也就是新元素要插入到这个元素之前。
                // 例子:在head中插入link 添加到最前面
                //       document.head.insertBefore(link, document.head.firstChild); 
                //       document.head.insertBefore(link, document.head.children[0]);  

                // 或者：document.head.insertBefore(link, document.head.lastChild); // 在head中插入link 添加到最后面
                // 或者：document.head.insertBefore(link, document.querySelector('title')); // 在head中插入link 添加到title前面
            } else {
                // 动态设置 light 和 dark 主题
                bodyTheme.setAttribute('data-theme', selectWrap.value);
            }
        }

        /* 
        移除 system 主题 函数：
        有时候切换系统主题了，项目还要刷新一下：
        因为系统主题的切换需要重新加载样式表才能生效，但有时候页面中的部分元素已经渲染出来，
        样式表被加载后并不会自动刷新渲染结果。在这种情况下，动态移除和添加样式表就能解决这个问题。
        */
        function removeSystemLink() {
            const link = document.querySelector('#system');
            if (link) link.remove();
        }
    </script>
</body>

</html>